import hashlib
import json
import time
import os
import struct
import functools
from api.WebTime import Nettime

def get_file_split(path):
    '''
    返回文件名与文件后缀
    '''
    return os.path.basename(path),os.path.splitext(path)[-1]

def encryp_sha1(string,key):
    utf = (string+key).encode('utf-8')
    high = hashlib.sha1(utf)
    high.update(key.encode('utf-8'))
    high_res = high.hexdigest()
    return high_res

def write_200_file(path,str):
    with open(path,'w') as f:
        f.write(str)

def read_encrypt_file(path):
    with open(path, 'rb') as f:
        return f.read(200)

def read_late_encrypt(path):
    with open(path, 'rb') as f:
        return f.read()[200:]

def create_json(timestamp, time_across,source_path):
    file_name,end_name = get_file_split(source_path)
    return json.dumps({'timestamp': timestamp, 'time_across': time_across, 'file_name': file_name, 'file_format': end_name})


def write_ahead(timestamp, time_crose,info_file_path, source_path, des_path):
    '''
    写入200个字符，但是会覆盖原有内容，所以要先创建文件，写好内容，再接上其他内容
    '''
    string = create_json(timestamp, time_crose, info_file_path)

    if len(string) < 200:
        f = open(source_path, 'wb')
        for m in str(string):
            f.write(m.encode('utf-8'))

        for i in range(200 - len(string)):
            f.write(b'_')

        file = write_append(des_path)
        f.write(file)
        return True
    else:
        print('密码长度错误！')


def write_append(content_path):
    af = open(content_path, 'rb')
    file = af.read()
    af.close()
    return file


def analyse_data(path):
    b_text = read_encrypt_file(path)
    d_text = bytes.decode(b_text)
    # print (d_text)
    res = json.loads(d_text.strip('_'))
    return res

def get_ntime():
    nettime = Nettime()
    ntime = 0
    try:
        ntime = nettime.taobao()
    except:
        try:
            ntime = nettime.pdd()
        except:
            try:
                ntime = nettime.huawei()
            except:
                ntime = nettime.beijing()
    return ntime

def is_arrive_time(path):
    nettime = Nettime()
    try:
        ntime = nettime.taobao()
    except:
        try:
            ntime = nettime.pdd()
        except:
            try:
                ntime = nettime.huawei()
            except:
                ntime = nettime.beijing()


    now_time = ntime
    print (now_time)
    res = analyse_data(path)
    time_arive = int(res['timestamp']) + int(res['time_across'])
    if time_arive < int(now_time):
        return True,''
    else:
        left_time = time_arive-int(now_time)
        print (f'还需要{left_time}秒才能解锁,约{int(left_time/86400)}天')
        return False,left_time



'''
文件进制转换
'''


def encode(s):
    tmp = []
    for c in s:
        tmp.append(bin(ord(c)).replace('0b', ''))
    str_bin = ' '.join(tmp)
    return (str_bin)


def decode(s):
    bin_str = ''.join([chr(i) for i in [int(b, 2) for b in s.split(' ')]])
    return bin_str


def fill_key(file, key):
    passwd = []
    file_len = len(file)
    while len(passwd) < file_len:
        # print (len(passwd),file_len)
        for i in key:
            passwd.append(i)
    return passwd[:file_len]


def fill_8(user_list):
    list2 = []
    for i in user_list:
        while len(i) < 8:
            i = '0' + i
        list2.append(i)
    return list2


def file_encode(path):
    f = open(path, 'rb')
    tmp = []
    for i in f.read():
        tmp.append(bin(i).replace('0b', ''))
    f.close()
    return (tmp)


def process_file(source, key):
    out = []
    for i in source:
        tmp = []
        tmp2 = []
        for b, key in zip(i, ''.join(fill_key(i, encode('hello').replace(' ', '')))):
            tmp.append(int(b) ^ int(key))
        for num in tmp:
            tmp2.append(str(num))
        st = ''.join(tmp2)
        out.append(st)
    return out



def file_decode(source, des_path):
    f = open(des_path, 'wb')
    for x in source:
        a = struct.pack('B', int(x, 2))
        f.write(a)
    f.close()
    return True

def byteen(from_path,key,outpath):
    source = file_encode(from_path)
    fill_source = fill_8(source)
    #print(fill_source)
    process_res = process_file(fill_source, key=key)
    file_decode(process_res, outpath)

def bytede(from_path,key,outpath):
    source = file_encode(from_path)
    fill_source = fill_8(source)
    #print(fill_source)
    process_res = process_file(fill_source, key=key)
    file_decode(process_res, outpath)


def clock(func):
    """this is outer clock function"""

    @functools.wraps(func)  # --> 4
    def clocked(*args, **kwargs):  # -- 1
        """this is inner clocked function"""
        start_time = time.time()
        result = func(*args, **kwargs)  # --> 2
        time_cost = time.time() - start_time
        print(func.__name__ + " func time_cost -> {}".format(time_cost))
        return result
    return clocked  # --> 3

@functools.lru_cache()
@clock
def encode_file(des_path,now_time,time_cross,key):
    passwd = encryp_sha1(str(now_time) + str(time_cross) + key, key)

    # 提示：1小时=3600秒，1天=86400秒，一年=31536000秒。
    # time.ctime(1629798961+157680000)

    #压缩
    #compress_to_zip([r'H:\helo.txt'], passwd=passwd)

    #异或
    from_path = des_path
    out_path = r'./addtion.lock'
    byteen(from_path,passwd,out_path)

    # 驳接
    from_path = r'./secret.lock'
    write_ahead(int(now_time), time_cross,des_path, from_path, out_path)
    # read_res = read_encrypt_file(des_path)
    # print(analyse_data(source_path))


    #删除垃圾
    os.remove(out_path)
    #os.remove(r'./output.zip')
    print ('Done')

@functools.lru_cache()
@clock
def decode_file(key):
    # 第一步获取网络时间，目前还没做。

    secret_path = './secret.lock'
    time_info = analyse_data(secret_path)
    print(time_info)
    passwd = encryp_sha1(str(time_info['timestamp']) + str(time_info['time_across']) + key, key)  # 获取密码
    print(passwd)
    #将200byte以后的内容作为文件保存
    file = read_late_encrypt(secret_path)
    temp_path = './temp.lock'
    result_path = './'+time_info['file_name']+'（已解锁）'+time_info['file_format']
    with open (temp_path,'wb') as f:
        f.write(file)

    #异或解密
    bytede(temp_path,passwd,result_path)
    #解压解密
    #unpress_zip(passwd=passwd)

    #清理垃圾
    os.remove(temp_path)
    #os.remove('./my_encode.zip')
    print ('Done')

def show_lock_info():
    secret_path = './secret.lock'
    time_info = analyse_data(secret_path)
    print(time_info)


if __name__ == '__main__':
    now_time = int(time.time())
    time_cross = 500
    key = 'passwwd'
    mypath = r'C:\Users\35992\Code\gitee\time-unlock\世界上下五千年——古代卷.txt'

    #encode_file(mypath,now_time,time_cross,key)

    #decode_file(key)

    secret_path = './secret.lock'
    show_lock_info()
    print (is_arrive_time(secret_path))